home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / OS / FWGraphx / Sources / PRBitmap.cpp < prev    next >
Encoding:
Text File  |  1996-04-25  |  34.8 KB  |  1,307 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                PRBitmap.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef SLPALETE_H
  13. #include "SLPalete.h"
  14. #endif
  15.  
  16. #ifndef FWODEXCE_H
  17. #include "FWODExce.h"
  18. #endif
  19.  
  20. #ifndef FWBITMAP_H
  21. #include "FWBitmap.h"
  22. #endif
  23.  
  24. #ifndef PRBITMAP_H
  25. #include "PRBitmap.h"
  26. #endif
  27.  
  28. #ifndef SLGC_H
  29. #include "SLGC.h"
  30. #endif
  31.  
  32. #ifndef FWWINRES_H
  33. #include "FWWinRes.h"
  34. #endif
  35.  
  36. #ifndef FWSTRMRW_H
  37. #include "FWStrmRW.h"
  38. #endif
  39.  
  40. #ifndef FWRESOUR_H
  41. #include "FWResour.h"
  42. #endif
  43.  
  44. #ifndef FWGRUTIL_H
  45. #include "FWGrUtil.h"
  46. #endif
  47.  
  48. #ifndef FWPALETE_H
  49. #include "FWPalete.h"
  50. #endif
  51.  
  52. #ifndef FWSOMENV_H
  53. #include "FWSOMEnv.h"
  54. #endif
  55.  
  56. #ifndef PRGRUTIL_H
  57. #include "PRGrUtil.h"
  58. #endif
  59.  
  60. #ifndef   FWMEMHLP_H
  61. #include "FWMemHlp.h"
  62. #endif
  63.  
  64. #ifndef FWEXCEPT_H
  65. #include "FWExcept.h"
  66. #endif
  67.  
  68. #if defined(FW_BUILD_WIN) && !defined(FWWINDIB_H)
  69. #include "FWWinDIB.h"
  70. #endif
  71.  
  72. #if defined(FW_BUILD_MAC) && !defined(__PICTUTILS__)
  73. #include <PictUtils.h>
  74. #endif
  75.  
  76. #ifndef PRPICTUR_H
  77. #include "PRPictur.h"
  78. #endif
  79.  
  80. //========================================================================================
  81. //    RunTime Info
  82. //========================================================================================
  83.  
  84. #ifdef FW_BUILD_MAC
  85. #pragma segment FW_Graphics
  86. #endif
  87.  
  88. FW_DEFINE_AUTO(FW_CPrivBitmapRep)
  89.  
  90. //========================================================================================
  91. // CLASS FW_CPrivBitmapRep
  92. //========================================================================================
  93.  
  94. #ifdef FW_BUILD_MAC
  95.  
  96. // Special Russian value swapping: uses no temporary
  97.  
  98. #define SWAP(a, b)     do { (a) = (a) ^ (b);    (b) = (a) ^ (b); (a) = (a) ^ (b); } while(0)
  99.  
  100. //----------------------------------------------------------------------------------------
  101. //    MacRepackResourceRow
  102. //----------------------------------------------------------------------------------------
  103.  
  104. static void MacRepackResourceRow(char* curBuffer, short bitDepth, short resRowBytes)
  105. {
  106.     short pixelBytes = bitDepth / 8;
  107.  
  108.     if(pixelBytes == 2)
  109.     {
  110.         do
  111.         {
  112.             SWAP(curBuffer[0], curBuffer[1]);
  113.         }
  114.         while((resRowBytes -= pixelBytes) > 0);
  115.     }
  116.     else if(pixelBytes == 4)
  117.     {
  118.         do
  119.         {
  120.             SWAP(curBuffer[0], curBuffer[3]);
  121.             SWAP(curBuffer[1], curBuffer[2]);
  122.         }
  123.         while((resRowBytes -= pixelBytes) > 0);
  124.     }
  125. }
  126.  
  127. //----------------------------------------------------------------------------------------
  128. //    MacRepackValue
  129. //----------------------------------------------------------------------------------------
  130.  
  131. static void MacRepackValue(short* s)
  132. {
  133.     char* c = (char*) s;
  134.     SWAP(c[0], c[1]);
  135. }
  136.  
  137. static void MacRepackValue(unsigned short* s)
  138. {
  139.     char* c = (char*) s;
  140.     SWAP(c[0], c[1]);
  141. }
  142.  
  143. static void MacRepackValue(long* l)
  144. {
  145.     char* c = (char*) l;
  146.     SWAP(c[0], c[3]);
  147.     SWAP(c[1], c[2]);
  148. }
  149.  
  150. static void MacRepackValue(unsigned long* l)
  151. {
  152.     char* c = (char*) l;
  153.     SWAP(c[0], c[3]);
  154.     SWAP(c[1], c[2]);
  155. }
  156.  
  157. #endif
  158.  
  159. //----------------------------------------------------------------------------------------
  160. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  161. //----------------------------------------------------------------------------------------
  162. // From image: will own the bitmap
  163.  
  164. FW_CPrivBitmapRep::FW_CPrivBitmapRep(short width,  short height,
  165.                                     short pixelSize, FW_Palette palette,
  166.                                     void* image, long imageSize, short rowBytes) :
  167.     fOwnBitmap(TRUE),
  168.     fPlatformBitmap(NULL)
  169. {
  170. #ifdef FW_BUILD_MAC
  171.     fLockCount = 0;
  172.     fPixMapHandle = NULL;
  173. #endif
  174. #ifdef FW_BUILD_WIN
  175.     fUserColorDepth = 0;
  176.     fWinPalette = NULL;
  177. #endif
  178.  
  179.     PrivMakeBitmap(width, height, pixelSize, palette);
  180.         
  181.     if (image != NULL)
  182.         SetImage(image, imageSize, rowBytes);
  183.         
  184.     FW_END_CONSTRUCTOR
  185. }
  186.  
  187. //----------------------------------------------------------------------------------------
  188. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  189. //----------------------------------------------------------------------------------------
  190. // From platform bitmap: will not own the bitmap
  191.  
  192. FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_PlatformBitmap platformBitmap) :
  193.     fOwnBitmap(FALSE),
  194.     fPlatformBitmap(platformBitmap)
  195. {
  196. #ifdef FW_BUILD_MAC
  197.     fLockCount = 0;
  198.     fPixMapHandle = NULL;
  199. #endif
  200. #ifdef FW_BUILD_WIN
  201.     fUserColorDepth = FW_DDBGetColorDepth(fPlatformBitmap);
  202.     fWinPalette = NULL;
  203. #endif
  204.  
  205.     FW_END_CONSTRUCTOR
  206. }
  207.  
  208. //----------------------------------------------------------------------------------------
  209. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  210. //----------------------------------------------------------------------------------------
  211. // From resources: will own the bitmap
  212.  
  213. FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_OResourceFile* resourceFile, FW_ResourceId resId) :
  214.     fOwnBitmap(TRUE),
  215.     fPlatformBitmap(NULL)
  216. {
  217. #ifdef FW_BUILD_MAC
  218.     fLockCount = 0;
  219.     fPixMapHandle = NULL;
  220. #endif
  221. #ifdef FW_BUILD_WIN
  222.     fUserColorDepth = 0;
  223.     fWinPalette = NULL;
  224. #endif
  225.  
  226.     fPlatformBitmap = NULL;
  227.  
  228.     FW_SOMEnvironment ev;
  229.     FW_PResource resource(ev, resourceFile, resId, FW_kBitmap);
  230.     FW_PResourceSink sink(ev, resource);
  231.     FW_CReadableStream stream(sink);
  232.  
  233. #ifdef FW_BUILD_WIN
  234.     PrivReadFromStream(stream, FALSE);
  235. #endif
  236. #ifdef FW_BUILD_MAC
  237.     PrivReadFromStream(stream, TRUE);
  238. #endif
  239.     
  240.     FW_END_CONSTRUCTOR
  241. }
  242.  
  243. //----------------------------------------------------------------------------------------
  244. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  245. //----------------------------------------------------------------------------------------
  246. // From another bitmap: will own the bitmap (a copy is made)
  247.  
  248. FW_CPrivBitmapRep::FW_CPrivBitmapRep(const FW_CPrivBitmapRep& bitmap, const FW_SRect& srcRect) :
  249.     fOwnBitmap(TRUE),
  250.     fPlatformBitmap(NULL)    
  251. {
  252. #ifdef FW_BUILD_MAC
  253.     fLockCount = 0;
  254.     fPixMapHandle = NULL;
  255. #endif
  256. #ifdef FW_BUILD_WIN
  257.     fUserColorDepth = 0;
  258.     fWinPalette = NULL;
  259. #endif
  260.  
  261.     FW_CRect bounds;
  262.     bitmap.GetBitmapBounds(bounds);
  263.     
  264.     FW_CRect clipRect = srcRect;
  265.  
  266.     if (clipRect.left < FW_kFixed0) 
  267.         clipRect.left = FW_kFixed0;
  268.     else if (clipRect.left > bounds.right) 
  269.         clipRect.left = bounds.right;
  270.         
  271.     if (clipRect.top < FW_kFixed0) 
  272.         clipRect.top = FW_kFixed0;
  273.     else if (clipRect.top > bounds.bottom) 
  274.         clipRect.top = bounds.bottom;
  275.     
  276.     if (clipRect.right > bounds.right) 
  277.         clipRect.right = bounds.right;
  278.     else if (clipRect.right < clipRect.left)
  279.         clipRect.right = clipRect.left;
  280.     
  281.     if (clipRect.bottom > bounds.bottom) 
  282.         clipRect.bottom = bounds.bottom;
  283.     else if (clipRect.bottom < clipRect.top) 
  284.         clipRect.bottom = clipRect.top;
  285.  
  286.     FW_CRect dstRect(FW_kFixed0, FW_kFixed0, clipRect.right - clipRect.left, clipRect.bottom - clipRect.top);
  287.  
  288.     short width, height, rowBytes, pixelSize;
  289.     bitmap.GetBitmapInfo(width, height, rowBytes, pixelSize);
  290.     
  291.     FW_Palette palette = bitmap.GetPalette();
  292.     PrivMakeBitmap(
  293.         FW_FixedToInt(clipRect.right - clipRect.left),
  294.         FW_FixedToInt(clipRect.bottom - clipRect.top), pixelSize, palette);
  295.  
  296.     bitmap.CopyPixels(*this, clipRect, dstRect);
  297.     
  298.     FW_END_CONSTRUCTOR
  299. }
  300.  
  301. //----------------------------------------------------------------------------------------
  302. //    FW_CPrivBitmapRep::~FW_CPrivBitmapRep
  303. //----------------------------------------------------------------------------------------
  304.  
  305. FW_CPrivBitmapRep::~FW_CPrivBitmapRep()
  306. {
  307.     PrivDisposeBitmap();
  308. }
  309.  
  310. //----------------------------------------------------------------------------------------
  311. //    FW_CPrivBitmapRep::IsEqual
  312. //----------------------------------------------------------------------------------------
  313.  
  314. FW_Boolean FW_CPrivBitmapRep::IsEqual(const FW_CPrivBitmapRep& bitmap) const
  315. {
  316.     return fPlatformBitmap == bitmap.fPlatformBitmap;
  317. }
  318.  
  319. //----------------------------------------------------------------------------------------
  320. //    FW_CPrivBitmapRep::Write
  321. //----------------------------------------------------------------------------------------
  322.  
  323. void FW_CPrivBitmapRep::Write(FW_CWritableStream& stream, FW_Boolean bDIBFileHeader)
  324. {
  325. #ifdef FW_BUILD_MAC
  326.     // Lock the GWorld pixmap
  327.     FW_CPrivMacPixelLock lock(this);
  328.     PixMapHandle pmh = lock.GetPixMapHandle();
  329.  
  330.     short        width        = (*pmh)->bounds.right;
  331.     short        height         = (*pmh)->bounds.bottom;
  332.     short        bitDepth    = (*pmh)->pixelSize;
  333.     
  334.     short        resRowBytes    = ((width * bitDepth + 31) & ~31) / 8;
  335.     short        memRowBytes    = (*pmh)->rowBytes & 0x7FFF;
  336.  
  337.     FW_ASSERT(resRowBytes <= memRowBytes);
  338.  
  339.     long imageSize = height * resRowBytes;
  340.  
  341.     // Determine color table size
  342.     int colorTableCount = bitDepth < 16 ? 1 << bitDepth : 0;
  343.     int colorTableSize  = colorTableCount * sizeof(RGBQUAD);
  344.  
  345.     // Create a file header
  346.     if(bDIBFileHeader)
  347.     {
  348.         BITMAPFILEHEADER bmfh;
  349.         bmfh.bfType                = FW_kWinBitmapSignature;
  350.         bmfh.bfSize                = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  351.                                 colorTableSize + imageSize;
  352.         bmfh.bfReserved1        = 0;
  353.         bmfh.bfReserved2        = 0;
  354.         bmfh.bfOffBits            = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  355.                                 colorTableSize;
  356.         
  357.         // Byte-swap and write it out
  358.         
  359.         MacRepackValue(&bmfh.bfType);
  360.         MacRepackValue(&bmfh.bfSize);
  361.         MacRepackValue(&bmfh.bfReserved1);
  362.         MacRepackValue(&bmfh.bfReserved2);
  363.         MacRepackValue(&bmfh.bfOffBits);
  364.         
  365.         stream.Write(&bmfh, sizeof(bmfh));
  366.     }
  367.  
  368.     // Create a DIB header
  369.  
  370.     BITMAPINFOHEADER bmih;
  371.  
  372.     bmih.biSize                = sizeof(BITMAPINFOHEADER);
  373.     bmih.biWidth            = width;
  374.     bmih.biHeight            = height;
  375.     bmih.biPlanes            = 1;
  376.     bmih.biBitCount            = bitDepth;
  377.     
  378.     bmih.biCompression        = 0;
  379.     bmih.biSizeImage        = imageSize;
  380.  
  381.     bmih.biXPelsPerMeter    = 0;
  382.     bmih.biYPelsPerMeter    = 0;
  383.     bmih.biClrUsed            = 0;
  384.     bmih.biClrImportant        = 0;
  385.     
  386.     // Byte-swap and write it out
  387.  
  388.     MacRepackValue(&bmih.biSize);
  389.     MacRepackValue(&bmih.biWidth);
  390.     MacRepackValue(&bmih.biHeight);
  391.     MacRepackValue(&bmih.biPlanes);
  392.     MacRepackValue(&bmih.biBitCount);
  393.     MacRepackValue(&bmih.biCompression);
  394.     MacRepackValue(&bmih.biSizeImage);
  395.     MacRepackValue(&bmih.biXPelsPerMeter);
  396.     MacRepackValue(&bmih.biYPelsPerMeter);
  397.     MacRepackValue(&bmih.biClrUsed);
  398.     MacRepackValue(&bmih.biClrImportant);
  399.  
  400.     stream.Write(&bmih, sizeof(bmih));
  401.  
  402.     // Write the color table (if applicable)
  403.     if(colorTableCount != 0)
  404.     {
  405.         CTabHandle cTabHandle = (*pmh)->pmTable;
  406.         FW_ASSERT(colorTableCount <= (*cTabHandle)->ctSize + 1);    // ctSize is count - 1!
  407.  
  408.         for(int i = 0; i < colorTableCount; ++i)
  409.         {
  410.             RGBQUAD quad;
  411.  
  412.             quad.rgbBlue        = (*cTabHandle)->ctTable[i].rgb.blue    >> 8;
  413.             quad.rgbGreen        = (*cTabHandle)->ctTable[i].rgb.green    >> 8;
  414.             quad.rgbRed            = (*cTabHandle)->ctTable[i].rgb.red        >> 8;
  415.             quad.rgbReserved    = 0;
  416.  
  417.             stream.Write(&quad, sizeof(quad));
  418.         }
  419.     }
  420.  
  421.     // Finally, do the bits (upside-down)
  422.     char* bitsBuffer = new char[memRowBytes];
  423.     
  424.     FW_TRY
  425.     {
  426.         const char* baseBuffer = ::GetPixBaseAddr(pmh);
  427.         const char* currBuffer = baseBuffer + memRowBytes * (height - 1);
  428.         
  429.         for(int row = height - 1; row >= 0; -- row, currBuffer -= memRowBytes)
  430.         {
  431.             ::BlockMove(currBuffer, bitsBuffer, resRowBytes);
  432.             MacRepackResourceRow(bitsBuffer, bitDepth, resRowBytes);
  433.             stream.Write(bitsBuffer, resRowBytes);
  434.         }
  435.     }
  436.     FW_CATCH_BEGIN
  437.     FW_CATCH_EVERYTHING()
  438.     {
  439.         delete[] bitsBuffer;
  440.         FW_THROW_SAME();
  441.     }
  442.     FW_CATCH_END
  443.     delete[] bitsBuffer;
  444. #endif
  445.  
  446. #ifdef FW_BUILD_WIN
  447.     // Convert to DIB first; use the color depth the user wanted
  448.     FW_WinDIB dib = FW_DIBConvertFromBitmap(fPlatformBitmap, fUserColorDepth, fWinPalette);
  449.     
  450.     FW_TRY
  451.     {
  452.         // Write out the DIB
  453.         FW_DIBSaveToStream(stream, dib, bDIBFileHeader);
  454.     }
  455.     FW_CATCH_BEGIN
  456.     FW_CATCH_EVERYTHING()
  457.     {
  458.         FW_DIBFree(dib);
  459.         FW_THROW_SAME();
  460.     }
  461.     FW_CATCH_END
  462.  
  463.     // Free the DIB
  464.     FW_DIBFree(dib);
  465. #endif
  466. }
  467.  
  468. //----------------------------------------------------------------------------------------
  469. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  470. //----------------------------------------------------------------------------------------
  471. // From a stream: will own the bitmap
  472.  
  473. FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_CReadableStream& stream, FW_Boolean bDIBFileHeader) :
  474.     fOwnBitmap(TRUE),
  475.     fPlatformBitmap(NULL)
  476. {
  477. #ifdef FW_BUILD_MAC
  478.     fLockCount = 0;
  479.     fPixMapHandle = NULL;
  480. #endif
  481. #ifdef FW_BUILD_WIN
  482.     fUserColorDepth = 0;
  483.     fWinPalette = NULL;
  484. #endif
  485.  
  486.     PrivReadFromStream(stream, bDIBFileHeader);
  487. }
  488.  
  489. //----------------------------------------------------------------------------------------
  490. //    FW_CPrivBitmapRep::GetPlatformBitmap
  491. //----------------------------------------------------------------------------------------
  492.  
  493. FW_PlatformBitmap  FW_CPrivBitmapRep::GetPlatformBitmap() const
  494. {
  495.     return fPlatformBitmap;
  496. }
  497.  
  498. //----------------------------------------------------------------------------------------
  499. //    FW_CPrivBitmapRep::IsPlatformBitmapOrphan
  500. //----------------------------------------------------------------------------------------
  501.  
  502. FW_Boolean FW_CPrivBitmapRep::IsPlatformBitmapOrphan() const
  503. {
  504.     return !fOwnBitmap;
  505. }
  506.  
  507. //----------------------------------------------------------------------------------------
  508. //    FW_CPrivBitmapRep::OrphanPlatformBitmap
  509. //----------------------------------------------------------------------------------------
  510.  
  511. FW_PlatformBitmap  FW_CPrivBitmapRep::OrphanPlatformBitmap()
  512. {
  513.     FW_ASSERT(fOwnBitmap);        // Only orphan once
  514.     fOwnBitmap = FALSE;
  515.     return fPlatformBitmap;
  516. }
  517.  
  518. //----------------------------------------------------------------------------------------
  519. //    FW_CPrivBitmapRep::SetPlatformBitmap
  520. //----------------------------------------------------------------------------------------
  521.  
  522. void FW_CPrivBitmapRep::SetPlatformBitmap(FW_PlatformBitmap newBitmap)
  523. {
  524.     if (fPlatformBitmap != newBitmap)
  525.     {
  526.         PrivDisposeBitmap();
  527.         fPlatformBitmap = newBitmap;
  528.     }
  529.     
  530.     fOwnBitmap = FALSE;
  531. }
  532.  
  533. //----------------------------------------------------------------------------------------
  534. //    FW_CPrivBitmapRep::AdoptPlatformBitmap
  535. //----------------------------------------------------------------------------------------
  536.  
  537. void FW_CPrivBitmapRep::AdoptPlatformBitmap(FW_PlatformBitmap newBitmap)
  538. {
  539.     SetPlatformBitmap(newBitmap);
  540.     fOwnBitmap = TRUE;
  541. }
  542.  
  543. //----------------------------------------------------------------------------------------
  544. //    FW_CPrivBitmapRep::GetPalette
  545. //----------------------------------------------------------------------------------------
  546.  
  547. FW_Palette FW_CPrivBitmapRep::GetPalette() const
  548. {
  549. #ifdef FW_BUILD_MAC
  550.     FW_CPrivMacPixelLock lock((FW_HBitmap)this);
  551.     PixMapHandle pmh = lock.GetPixMapHandle();
  552.     return (*pmh)->pmTable;
  553. #endif
  554. #ifdef FW_BUILD_WIN
  555.     return fWinPalette;
  556. #endif
  557. }
  558.  
  559. //----------------------------------------------------------------------------------------
  560. //    FW_CPrivBitmapRep::SetPalette
  561. //----------------------------------------------------------------------------------------
  562.  
  563. void FW_CPrivBitmapRep::SetPalette(FW_Palette palette)
  564. {
  565. #ifdef FW_BUILD_MAC
  566.     FW_CPrivMacPixelLock lock(this);
  567.     PixMapHandle pmh = lock.GetPixMapHandle();
  568.     CTabHandle oldTable = (*pmh)->pmTable;
  569.     (*pmh)->pmTable = palette;
  570.     ::DisposeHandle((Handle)oldTable);
  571. #endif
  572. #ifdef FW_BUILD_WIN
  573.     if (fWinPalette != NULL)
  574.         ::DeleteObject(fWinPalette);
  575.     fWinPalette = palette;
  576. #endif
  577. }
  578.  
  579. //----------------------------------------------------------------------------------------
  580. //    FW_CPrivBitmapRep::GetBitmapInfo
  581. //----------------------------------------------------------------------------------------
  582.  
  583. void FW_CPrivBitmapRep::GetBitmapInfo(
  584.         short& width,
  585.         short& height,
  586.         short& rowBytes,
  587.         short& pixelSize) const
  588. {
  589. #ifdef FW_BUILD_MAC
  590.     PixMapHandle pixMap = ::GetGWorldPixMap(fPlatformBitmap);
  591.  
  592.     width        = (*pixMap)->bounds.right - (*pixMap)->bounds.left;
  593.     height        = (*pixMap)->bounds.bottom - (*pixMap)->bounds.top;
  594.     rowBytes    = (*pixMap)->rowBytes & 0x7FFF;
  595.     pixelSize    = (*pixMap)->pixelSize;
  596. #endif
  597.  
  598. #ifdef FW_BUILD_WIN
  599.     BITMAP bm;
  600.     ::GetObject(fPlatformBitmap, sizeof(bm), &bm);
  601.  
  602.     width        = (short) bm.bmWidth;
  603.     height        = (short) bm.bmHeight;
  604.     rowBytes    = (short) bm.bmWidthBytes;
  605.     pixelSize    = fUserColorDepth;            // The actual DDB pixel size may differ
  606. #endif
  607. }
  608.  
  609. //----------------------------------------------------------------------------------------
  610. //    FW_CPrivBitmapRep::GetBitmapBoundsGC
  611. //----------------------------------------------------------------------------------------
  612.  
  613. void FW_CPrivBitmapRep::GetBitmapBoundsGC(Environment* ev, FW_SGraphicContext& gc, FW_SRect& bounds) const
  614. {
  615.     short width, height,rowBytes, pixelSize;
  616.     GetBitmapInfo(width, height, rowBytes, pixelSize);
  617.         
  618.     FW_CPoint size;
  619.     FW_PrivGC_DeviceToLogicalSize(ev, gc, width, height, size);
  620.     // let go if error
  621.     
  622.     bounds.left        = FW_kFixed0;
  623.     bounds.top        = FW_kFixed0;
  624.     bounds.right    = size.x;
  625.     bounds.bottom    = size.y;
  626. }
  627.  
  628. //----------------------------------------------------------------------------------------
  629. //    FW_CPrivBitmapRep::GetBitmapBounds
  630. //----------------------------------------------------------------------------------------
  631.  
  632. void FW_CPrivBitmapRep::GetBitmapBounds(FW_SRect& bounds) const
  633. {
  634.     short width, height,rowBytes, pixelSize;
  635.     GetBitmapInfo(width, height, rowBytes, pixelSize);
  636.  
  637.     bounds.left     = FW_IntToFixed(0);
  638.     bounds.top        = FW_IntToFixed(0);
  639.     bounds.right    = FW_IntToFixed(width);
  640.     bounds.bottom    = FW_IntToFixed(height);
  641. }
  642.  
  643. //----------------------------------------------------------------------------------------
  644. //    FW_CPrivBitmapRep::ChangeBitmap
  645. //----------------------------------------------------------------------------------------
  646.  
  647. FW_PlatformError FW_CPrivBitmapRep::ChangeBitmap(short         width,
  648.                                     short         height,
  649.                                     short         pixelSize,
  650.                                     FW_Boolean     bScale)
  651. {
  652.     FW_PlatformError error = FW_xNoError;
  653.     
  654. #ifdef FW_BUILD_MAC
  655.     FW_ASSERT(!MacIsPixelsLocked());
  656.     FW_CPlatformRect boundsRect(0, 0, width, height);
  657.     GWorldFlags flags = ::UpdateGWorld(&fPlatformBitmap, pixelSize, &boundsRect, NULL, NULL, bScale ? stretchPix : clipPix);
  658.     if (flags == gwFlagErr)
  659.         error = FW_xGraphicException;
  660. #endif
  661.  
  662. #ifdef FW_BUILD_WIN
  663.     // Determine color depth for the DDB
  664.     short bmNewPlanes = 1, bmNewBitsPixel = 1;
  665.     if(pixelSize != 1)
  666.         FW_PrivWinGetDisplayColorInfo(bmNewPlanes, bmNewBitsPixel);
  667.         
  668.     // Get the current bitmap depth
  669.     BITMAP bm;
  670.     ::GetObject(fPlatformBitmap, sizeof(bm), &bm);
  671.     
  672.     if(bm.bmPlanes != bmNewPlanes || bm.bmBitsPixel != bmNewBitsPixel ||
  673.         bm.bmWidth != width || bm.bmHeight != height)
  674.     {
  675.         // Create a new bitmap        
  676.         HBITMAP bitmap = ::CreateBitmap(width, height, bmNewPlanes, bmNewBitsPixel, NULL);
  677.         if(bitmap != NULL)
  678.         {
  679.             // Copy the bits
  680.             FW_CPlatformRect rectSrc(0, 0, bm.bmWidth, bm.bmHeight);
  681.             FW_CPlatformRect rectDst(0, 0, width, height);
  682.             FW_DDBCopyImage(
  683.                 bitmap, NULL, &rectDst,                 // Even if fWinPalette is not NULL,
  684.                 fPlatformBitmap, NULL, &rectSrc,        //  no color translation is needed here
  685.                 bScale
  686.                     ? FW_kScaleImage
  687.                     : FW_kCropImage);
  688.     
  689.             // Replace the platform bitmap
  690.             AdoptPlatformBitmap(bitmap);
  691.         }
  692.         else
  693.         {
  694.             error = FW_xGraphicException;
  695.         }
  696.     }
  697.  
  698.     // Update the color depth
  699.     if(pixelSize != 0 && error == FW_xNoError)
  700.         fUserColorDepth = pixelSize;
  701.     else
  702.         fUserColorDepth = FW_DDBGetColorDepth(fPlatformBitmap);
  703. #endif
  704.  
  705.     return error;
  706. }
  707.  
  708. //----------------------------------------------------------------------------------------
  709. //    FW_CPrivBitmapRep::ChangeBitmap
  710. //----------------------------------------------------------------------------------------
  711.  
  712. FW_PlatformError FW_CPrivBitmapRep::ChangeBitmap(void*         image,
  713.                                     long         imageSize,
  714.                                     short        rowBytes,
  715.                                     short         width,
  716.                                     short         height,
  717.                                     short         pixelSize,
  718.                                     FW_Boolean     bScale)
  719. {    
  720.     FW_ASSERT(image != NULL);
  721.     FW_PlatformError error = ChangeBitmap(width, height, pixelSize, bScale);
  722.     if (error == FW_xNoError)
  723.         error = SetImage(image, imageSize, rowBytes);
  724.     return error;
  725. }
  726.  
  727. //----------------------------------------------------------------------------------------
  728. //    FW_CPrivBitmapRep::SetImage
  729. //----------------------------------------------------------------------------------------
  730.  
  731. FW_PlatformError FW_CPrivBitmapRep::SetImage(void*     image,
  732.                                 long     imageSize,
  733.                                 short    rowBytes)
  734. {
  735.     short bmpHeight, bmpWidth, bmpRowBytes, bmpPixelSize;
  736.     GetBitmapInfo(bmpWidth, bmpHeight, bmpRowBytes, bmpPixelSize);
  737.  
  738.     FW_ASSERT(rowBytes <= bmpRowBytes);
  739.  
  740. #ifdef FW_BUILD_MAC
  741.     FW_CPrivMacPixelLock lock(this);
  742.     PixMapHandle pmh = lock.GetPixMapHandle();
  743.     Ptr baseAddr = ::GetPixBaseAddr(pmh);
  744.     
  745.     if (rowBytes == bmpRowBytes)
  746.     {
  747.         size_t toCopy = bmpHeight * bmpRowBytes;
  748.         if (toCopy > imageSize)
  749.             toCopy = imageSize;
  750.  
  751.         FW_PrimitiveCopyMemory(image, baseAddr, toCopy);
  752.     }
  753.     else
  754.     {
  755.         const char* srcPtr = (const char*) image;
  756.         char* dstPtr = baseAddr;
  757.         
  758.         for (
  759.             int nRow = 0;
  760.             nRow < bmpHeight && imageSize > 0;
  761.             ++nRow, imageSize -= rowBytes, srcPtr += rowBytes, dstPtr += bmpRowBytes
  762.             )
  763.             FW_PrimitiveCopyMemory(srcPtr, dstPtr, rowBytes);
  764.     }
  765. #endif
  766.  
  767. #ifdef FW_BUILD_WIN
  768.     if (rowBytes == bmpRowBytes)
  769.     {
  770.         ::SetBitmapBits(fPlatformBitmap, imageSize, image);
  771.     }
  772.     else
  773.     {
  774.         int nRowCount = imageSize / rowBytes;
  775.         FW_CAcquireTemporaryMemory tempMem(nRowCount * bmpRowBytes);
  776.         
  777.         const char* srcPtr = (const char*) image;
  778.         char* dstPtr = (char*) tempMem.GetPointer();
  779.  
  780.         for (
  781.             int nRow = 0;
  782.             nRow < bmpHeight && imageSize > 0;
  783.             ++nRow, imageSize -= rowBytes, srcPtr += rowBytes, dstPtr += bmpRowBytes
  784.             )
  785.             FW_PrimitiveCopyMemory(srcPtr, dstPtr, rowBytes);
  786.  
  787.         ::SetBitmapBits(fPlatformBitmap, nRowCount * bmpRowBytes, tempMem.GetPointer());
  788.     }
  789. #endif
  790.  
  791.     return FW_xNoError;
  792. }
  793.  
  794. //----------------------------------------------------------------------------------------
  795. //    FW_CPrivBitmapRep::CopyPixels
  796. //----------------------------------------------------------------------------------------
  797.  
  798. FW_PlatformError FW_CPrivBitmapRep::CopyPixels(FW_CPrivBitmapRep& dstBitmap, 
  799.                                     const FW_SRect& boundsSrc, 
  800.                                     const FW_SRect& boundsDst) const
  801. {
  802.     FW_RETURN_ERR_TRY
  803.     {
  804.         FW_CPlatformRect plfmSrcRect = boundsSrc;
  805.         FW_CPlatformRect plfmDstRect = boundsDst;
  806.  
  807. #ifdef FW_BUILD_MAC
  808.         FW_CPrivMacPixelLock srcLock((FW_HBitmap)this);
  809.         PixMapHandle srcPixMap = srcLock.GetPixMapHandle();
  810.     
  811.         FW_CPrivMacPixelLock dstLock(&dstBitmap);
  812.         PixMapHandle dstPixMap = dstLock.GetPixMapHandle();
  813.         
  814.         CGrafPtr     curPort;
  815.         GDHandle     gdh;
  816.         ::GetGWorld(&curPort, &gdh);
  817.         ::SetGWorld(dstBitmap.GetPlatformBitmap(), NULL);
  818.         ::CopyBits((BitMap*)*srcPixMap, (BitMap*)*dstPixMap,  
  819.                     &plfmSrcRect, &plfmDstRect, 
  820.                     srcCopy, NULL);
  821.         ::SetGWorld(curPort, gdh);    
  822. #endif
  823. #ifdef FW_BUILD_WIN
  824.         HBITMAP dstBitmapHandle = dstBitmap.GetPlatformBitmap();
  825.         HPALETTE hDstPalette = dstBitmap.GetPalette();
  826.     
  827.         FW_DDBCopyImage(dstBitmapHandle, hDstPalette, &plfmDstRect,
  828.                         fPlatformBitmap, fWinPalette, &plfmSrcRect,
  829.                         FW_kScaleImage);
  830. #endif
  831.     }
  832.     FW_RETURN_ERR_CATCH
  833. }
  834.  
  835. #ifdef FW_BUILD_MAC
  836.  
  837. //----------------------------------------------------------------------------------------
  838. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  839. //----------------------------------------------------------------------------------------
  840. // From a picture: will own the bitmap
  841.  
  842. FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_HPicture picture, FW_SColor fillColor, const FW_SRect& pictPart) :
  843.     fOwnBitmap(TRUE),
  844.     fPlatformBitmap(NULL)
  845. {
  846. #ifdef FW_BUILD_MAC
  847.     fLockCount = 0;
  848.     fPixMapHandle = NULL;
  849. #endif
  850. #ifdef FW_BUILD_WIN
  851.     fUserColorDepth = 0;
  852.     fWinPalette = NULL;
  853. #endif
  854.  
  855.     CGrafPtr curPort;
  856.     GDHandle gdh;
  857.     ::GetGWorld(&curPort, &gdh);
  858.  
  859.     //    It looks like I have to be in a 'valid' port before calling GetPictInfo
  860.     //    I don't know why but if I remove the following three lines I end up with
  861.     //    color problems.
  862.     CGrafPtr screenPort;
  863.     GetCWMgrPort(&screenPort);
  864.     ::SetPort((GrafPtr)screenPort);
  865.  
  866.     FW_PlatformPict pictHandle = picture->GetPlatformPict();
  867.     FW_ASSERT(pictHandle != 0);
  868.  
  869.     // Just get picture color depth    at first
  870.     PictInfo pictInfo;
  871.     ::GetPictInfo(pictHandle, &pictInfo, 0, 0, 0, 0);
  872.  
  873.     // Now that we know the color depth, we are ready to get the color table
  874.     short nColors = pictInfo.depth > 8 ? 256 : 1 << pictInfo.depth;
  875.     ::GetPictInfo(pictHandle, &pictInfo, returnColorTable, nColors, systemMethod, 0);
  876.  
  877.     // Create a GWorld
  878.     FW_CPlatformRect gworldRect = pictPart;
  879.     ::OffsetRect(&gworldRect, -gworldRect.left, -gworldRect.top);
  880.     QDErr err = ::NewGWorld(&fPlatformBitmap, pictInfo.depth, &gworldRect,
  881.         pictInfo.theColorTable, NULL, useTempMem);
  882.     FW_ASSERT(err == noErr);
  883.     
  884.     ::DisposeCTable(pictInfo.theColorTable);
  885.  
  886.     FW_FailOnError(err);
  887.     if(fPlatformBitmap == NULL)
  888.     {
  889.         ::SetGWorld(curPort, gdh);
  890.         FW_Failure(FW_xGraphicException);
  891.     }
  892.     
  893.     // Copy the image
  894.     ::SetGWorld(fPlatformBitmap, NULL);
  895.     
  896.     FW_CPrivMacPixelLock lock(this);
  897. //    PixMapHandle pmh = lock.GetPixMapHandle();
  898.  
  899.     FW_CColor odfColor = fillColor;
  900.     RGBColor macColor(odfColor);
  901.     ::RGBBackColor(&macColor);
  902.     ::EraseRect(&gworldRect);
  903.  
  904.  
  905.     odfColor = FW_kRGBBlack;
  906.     macColor = odfColor; 
  907.     ::RGBForeColor(&macColor);
  908.     odfColor = FW_kRGBWhite;
  909.     macColor = odfColor; 
  910.     ::RGBBackColor(&macColor);
  911.     ::PenNormal();
  912.     FW_CPlatformRect rectPicture = pictInfo.sourceRect;
  913.     ::OffsetRect(&rectPicture, - FW_FixedToInt(pictPart.left), - FW_FixedToInt(pictPart.top));
  914.     ::DrawPicture(pictHandle, &rectPicture);
  915.  
  916.     ::SetGWorld(curPort, gdh);
  917.     
  918.     FW_END_CONSTRUCTOR
  919. }
  920. #endif
  921.  
  922. #ifdef FW_BUILD_MAC
  923. //----------------------------------------------------------------------------------------
  924. //    FW_CPrivBitmapRep::MacGetAsPicture
  925. //----------------------------------------------------------------------------------------
  926.  
  927. FW_HPicture FW_CPrivBitmapRep::MacGetAsPicture(const FW_SRect& bounds) const
  928. {
  929.     CGrafPtr     curPort;
  930.     GDHandle     gdh;
  931.     ::GetGWorld(&curPort, &gdh);
  932.  
  933.     FW_CPrivMacPixelLock lock((FW_HBitmap)this);
  934.     PixMapHandle pixMap = lock.GetPixMapHandle();
  935.  
  936.     GDHandle gdevice = ::GetGWorldDevice(fPlatformBitmap);
  937.  
  938.     ::SetGWorld(fPlatformBitmap, gdevice);
  939.  
  940.     FW_CPlatformRect plfmSrcRect = bounds;
  941.     FW_CPlatformRect plfmDstRect = bounds;
  942.     ::OffsetRect(&plfmDstRect, -plfmDstRect.left, -plfmDstRect.top);
  943.  
  944.     OpenCPicParams openParams;
  945.     openParams.srcRect    = plfmDstRect;
  946.     openParams.hRes        =
  947.     openParams.vRes     = 0x00480000;
  948.     openParams.version    = -2;
  949.     openParams.reserved1 =
  950.     openParams.reserved2 = 0;
  951.  
  952.     PicHandle hPict = ::OpenCPicture(&openParams);
  953.     ::CopyBits((BitMap*)*pixMap, (BitMap*)*pixMap,  
  954.                 &plfmSrcRect, &plfmDstRect, 
  955.                 srcCopy, NULL);
  956.     ::ClosePicture();
  957.  
  958.     ::SetGWorld(curPort, gdh);
  959.  
  960.     return FW_NEW(FW_CPrivPictureRep, (hPict));
  961. }
  962.  
  963. #endif
  964.  
  965. #ifdef FW_BUILD_MAC
  966.  
  967. //----------------------------------------------------------------------------------------
  968. //    FW_CPrivBitmapRep::MacLockPixels
  969. //----------------------------------------------------------------------------------------
  970.  
  971. PixMapHandle FW_CPrivBitmapRep::MacLockPixels()
  972. {
  973.     if (++ fLockCount == 1)
  974.     {
  975.         FW_ASSERT(fPixMapHandle == NULL);
  976.         fPixMapHandle = ::GetGWorldPixMap(fPlatformBitmap);
  977.         ::LockPixels(fPixMapHandle);
  978.     }
  979.  
  980.     return fPixMapHandle;
  981. }
  982. #endif
  983.  
  984. #ifdef FW_BUILD_MAC
  985.  
  986. //----------------------------------------------------------------------------------------
  987. //    FW_CPrivBitmapRep::MacUnlockPixels
  988. //----------------------------------------------------------------------------------------
  989.  
  990. void FW_CPrivBitmapRep::MacUnlockPixels()
  991. {
  992.     FW_ASSERT(fPixMapHandle != NULL);
  993.     FW_ASSERT(fLockCount != 0);
  994.     
  995.     if (-- fLockCount == 0)
  996.     {
  997.         ::UnlockPixels(fPixMapHandle);    
  998.         fPixMapHandle = NULL;
  999.     }
  1000. }
  1001. #endif
  1002.  
  1003. #ifdef FW_BUILD_MAC
  1004. //----------------------------------------------------------------------------------------
  1005. //    FW_CPrivBitmapRep::MacIsPixelsLocked
  1006. //----------------------------------------------------------------------------------------
  1007.  
  1008. FW_Boolean FW_CPrivBitmapRep::MacIsPixelsLocked() const
  1009. {
  1010.     return fLockCount != 0;
  1011. }
  1012. #endif
  1013.  
  1014. //----------------------------------------------------------------------------------------
  1015. //    FW_CPrivBitmapRep::PrivDisposeBitmap
  1016. //----------------------------------------------------------------------------------------
  1017.  
  1018. void FW_CPrivBitmapRep::PrivDisposeBitmap()
  1019. {
  1020.     if (fOwnBitmap && fPlatformBitmap != NULL)
  1021.     {
  1022. #ifdef FW_BUILD_MAC
  1023.         ::DisposeGWorld(fPlatformBitmap);
  1024. #endif
  1025. #ifdef FW_BUILD_WIN
  1026.         ::DeleteObject(fPlatformBitmap);
  1027.         
  1028.         if (fWinPalette != NULL)
  1029.         {
  1030.             ::DeleteObject(fWinPalette);
  1031.             fWinPalette = NULL;
  1032.         }
  1033. #endif
  1034.     }
  1035.  
  1036.     fPlatformBitmap = NULL;
  1037.     fOwnBitmap = FALSE;
  1038. }
  1039.  
  1040. //----------------------------------------------------------------------------------------
  1041. //    FW_CPrivBitmapRep::PrivMakeBitmap
  1042. //----------------------------------------------------------------------------------------
  1043.  
  1044. void FW_CPrivBitmapRep::PrivMakeBitmap(
  1045.         short width, short height,
  1046.         short pixelSize, FW_Palette palette)
  1047. {
  1048.     FW_PlatformBitmap bitmap = NULL;
  1049.     
  1050.     FW_ASSERT(height != 0);
  1051.     FW_ASSERT(width != 0);
  1052.     
  1053. #ifdef FW_BUILD_MAC
  1054.     FW_CPlatformRect boundsRect(0, 0, width, height);
  1055.  
  1056.     OSErr err = ::NewGWorld(&bitmap, pixelSize, &boundsRect, palette, NULL, useTempMem);
  1057.     FW_FailOnError(err);
  1058. #endif
  1059. #ifdef FW_BUILD_WIN
  1060.     // Determine color depth for the DDB
  1061.     short bmPlanes = 1, bmBitsPixel = 1;
  1062.     if(pixelSize != 1)
  1063.         FW_PrivWinGetDisplayColorInfo(bmPlanes, bmBitsPixel);
  1064.  
  1065.     // Create the bitmap    
  1066.     bitmap = ::CreateBitmap(width, height, bmPlanes, bmBitsPixel, NULL);
  1067.     if(bitmap == NULL)
  1068.         FW_Failure(FW_xMemoryExhausted);
  1069.  
  1070.     // Update the color depth
  1071.     if(pixelSize != 0)
  1072.         fUserColorDepth = pixelSize;
  1073.     else
  1074.         fUserColorDepth = FW_DDBGetColorDepth(bitmap);
  1075.         
  1076.     // Copy the palette if there is one
  1077.     if (palette != NULL)
  1078.         fWinPalette = FW_CopyPalette(palette);
  1079. #endif
  1080.  
  1081.     fPlatformBitmap    = bitmap;
  1082.     fOwnBitmap    = TRUE;
  1083. }
  1084.  
  1085. //----------------------------------------------------------------------------------------
  1086. //    FW_CPrivBitmapRep::PrivReadFromStream
  1087. //----------------------------------------------------------------------------------------
  1088.  
  1089. void FW_CPrivBitmapRep::PrivReadFromStream(FW_CReadableStream& stream, FW_Boolean bDIBFileHeader)
  1090. {
  1091. #ifdef FW_BUILD_WIN
  1092.     FW_WinDIB dib = FW_DIBLoadFromStream(stream, bDIBFileHeader);
  1093.     
  1094.     // Get the palette
  1095.     fWinPalette = FW_DIBGetPalette(dib);
  1096.  
  1097.     FW_TRY
  1098.     {
  1099.         fPlatformBitmap = FW_DIBConvertToBitmap(dib, fWinPalette);
  1100.     }
  1101.     FW_CATCH_BEGIN
  1102.     FW_CATCH_EVERYTHING()
  1103.     {
  1104.         FW_DIBFree(dib);
  1105.         FW_THROW_SAME();
  1106.     }
  1107.     FW_CATCH_END
  1108.     
  1109.     FW_DIBFree(dib);
  1110.  
  1111.     // Update the color depth
  1112.     fUserColorDepth = FW_DDBGetColorDepth(fPlatformBitmap);
  1113. #endif
  1114.  
  1115. #ifdef FW_BUILD_MAC
  1116.     // Read the BITMAPFILEINFO header
  1117.     if(bDIBFileHeader)
  1118.     {
  1119.         BITMAPFILEHEADER bmfh;
  1120.         
  1121.         stream.Read((void*) &bmfh, sizeof(bmfh));
  1122.         
  1123.         MacRepackValue(&bmfh.bfType);
  1124.         MacRepackValue(&bmfh.bfSize);
  1125.         MacRepackValue(&bmfh.bfReserved1);
  1126.         MacRepackValue(&bmfh.bfReserved2);
  1127.         MacRepackValue(&bmfh.bfOffBits);
  1128.     
  1129.         if(bmfh.bfType != FW_kWinBitmapSignature || bmfh.bfReserved1 != 0 || bmfh.bfReserved2 != 0)        
  1130.             FW_Failure(FW_xInvalidBitmapData);
  1131.     }
  1132.  
  1133.     // Start reading the header
  1134.     FW_Boolean bIsWindowsBitmap;
  1135.     BITMAPINFOHEADER bmih;
  1136.  
  1137.     stream.Read((void*) &bmih.biSize, sizeof(bmih.biSize));
  1138.  
  1139.     MacRepackValue(&bmih.biSize);
  1140.  
  1141.     if(bmih.biSize == sizeof(BITMAPINFOHEADER))                // Windows bitmap
  1142.     {
  1143.         // Read the Windows header
  1144.         stream.Read((void*) &bmih.biWidth, sizeof(bmih) - sizeof(bmih.biSize));
  1145.         
  1146.         MacRepackValue(&bmih.biWidth);
  1147.         MacRepackValue(&bmih.biHeight);
  1148.         MacRepackValue(&bmih.biPlanes);
  1149.         MacRepackValue(&bmih.biBitCount);
  1150.         MacRepackValue(&bmih.biCompression);
  1151.         MacRepackValue(&bmih.biSizeImage);
  1152.         MacRepackValue(&bmih.biXPelsPerMeter);
  1153.         MacRepackValue(&bmih.biYPelsPerMeter);
  1154.         MacRepackValue(&bmih.biClrUsed);
  1155.         MacRepackValue(&bmih.biClrImportant);
  1156.  
  1157.         bIsWindowsBitmap = TRUE;
  1158.     }
  1159.     else if(bmih.biSize == sizeof(BITMAPCOREHEADER))        // OS/2 bitmap
  1160.     {
  1161.         // Read the OS/2 header
  1162.         BITMAPCOREHEADER bmch;
  1163.         
  1164.         stream.Read((void* )&bmch.bcWidth, sizeof(bmch) - sizeof(bmch.bcSize));
  1165.  
  1166.         MacRepackValue(&bmch.bcWidth);
  1167.         MacRepackValue(&bmch.bcHeight);
  1168.         MacRepackValue(&bmch.bcPlanes);
  1169.         MacRepackValue(&bmch.bcBitCount);
  1170.  
  1171.         // Plug the data into the Windows header
  1172.         bmih.biWidth            =    bmch.bcWidth;
  1173.         bmih.biHeight            =    bmih.biHeight;
  1174.         bmih.biPlanes            =    bmch.bcPlanes;
  1175.         bmih.biBitCount            =    bmch.bcBitCount;
  1176.         bmih.biCompression        =    0;
  1177.         bmih.biSizeImage        =    0;
  1178.         bmih.biXPelsPerMeter    =    0;
  1179.         bmih.biYPelsPerMeter    =    0;
  1180.         bmih.biClrUsed            =    0;
  1181.         bmih.biClrImportant        =    0;
  1182.  
  1183.         bIsWindowsBitmap = FALSE;
  1184.     }
  1185.     else
  1186.         FW_Failure(FW_xInvalidBitmapData);
  1187.  
  1188.     // Check for compression flag -- we don't support it!
  1189.     if(bmih.biCompression != 0)
  1190.         FW_Failure(FW_xInvalidBitmapData);
  1191.  
  1192.     // Determine the size of the color table
  1193.     short bitDepth = bmih.biBitCount;
  1194.     short colorCount = bmih.biClrUsed != 0 ? bmih.biClrUsed : bitDepth >= 16 ? 0 : (1 << bitDepth);
  1195.  
  1196.     // Read the color table
  1197.     CTabHandle colorTabHandle = NULL;
  1198.     if(colorCount != 0)
  1199.     {
  1200.         Size colorTableSize = sizeof(ColorTable) + sizeof(ColorSpec) * (colorCount - 1);
  1201.         FW_CAcquireTemporarySystemHandle colorTableMemory(colorTableSize);
  1202.         CTabPtr colorTablePtr = (CTabPtr) colorTableMemory.GetPointer();
  1203.  
  1204.         for(int i = 0; i < colorCount; colorTablePtr->ctTable[i].value = i, ++i)
  1205.         {
  1206.             if(bIsWindowsBitmap)
  1207.             {
  1208.                 RGBQUAD quad;
  1209.                 stream.Read((void*) &quad, sizeof(quad));
  1210.                     
  1211.                 colorTablePtr->ctTable[i].rgb.red    = (quad.rgbRed        << 8) | quad.rgbRed;
  1212.                 colorTablePtr->ctTable[i].rgb.green    = (quad.rgbGreen    << 8) | quad.rgbGreen;
  1213.                 colorTablePtr->ctTable[i].rgb.blue    = (quad.rgbBlue        << 8) | quad.rgbBlue;
  1214.             }
  1215.             else
  1216.             {
  1217.                 RGBTRIPLE trip;
  1218.                 stream.Read((void*) &trip, sizeof(trip));
  1219.                     
  1220.                 colorTablePtr->ctTable[i].rgb.red    = trip.rgbtRed    << 8;
  1221.                 colorTablePtr->ctTable[i].rgb.green    = trip.rgbtGreen<< 8;
  1222.                 colorTablePtr->ctTable[i].rgb.blue    = trip.rgbtBlue    << 8;
  1223.             }
  1224.         }
  1225.  
  1226.         colorTablePtr->ctSeed    = 0;
  1227.         colorTablePtr->ctFlags    = 0;
  1228.         colorTablePtr->ctSize    = colorCount - 1;
  1229.  
  1230.         colorTabHandle = (CTabHandle) colorTableMemory.Orphan();
  1231.         
  1232.         ::CTabChanged(colorTabHandle);
  1233.     }
  1234.  
  1235.     // Create a GWorld
  1236.     FW_CPlatformRect bounds(0, 0, bmih.biWidth, bmih.biHeight);
  1237.     OSErr err = ::NewGWorld(&fPlatformBitmap, bitDepth, &bounds,
  1238.         colorTabHandle, NULL, useTempMem);
  1239.  
  1240.     if (colorTabHandle != NULL)
  1241.         ::DisposeCTable(colorTabHandle);
  1242.  
  1243.     FW_FailOnError(err);
  1244.  
  1245.     // Lock the memory pixmap
  1246.     FW_CPrivMacPixelLock lock(this);
  1247.     PixMapHandle memPixMap = lock.GetPixMapHandle();
  1248.     void* memBaseAddr = ::GetPixBaseAddr(memPixMap);
  1249.  
  1250.     // Read the bits
  1251.     short resRowBytes = ((bmih.biWidth * bitDepth + 31) & ~31) / 8;
  1252.     short memRowBytes = (*memPixMap)->rowBytes & 0x7FFF;
  1253.     FW_ASSERT(resRowBytes <= memRowBytes);
  1254.  
  1255.     char* curBuffer    = (char*) memBaseAddr + (bmih.biHeight - 1) * memRowBytes;
  1256.     
  1257.     for(int row = bmih.biHeight - 1; row >= 0; -- row, curBuffer -= memRowBytes)
  1258.     {
  1259.         // Read and repack the next row
  1260.         stream.Read(curBuffer, resRowBytes);
  1261.         MacRepackResourceRow(curBuffer, bitDepth, resRowBytes);
  1262.     }
  1263. #endif
  1264. }
  1265.  
  1266. #ifdef FW_BUILD_MAC
  1267.  
  1268. //========================================================================================
  1269. // CLASS FW_CPrivMacPixelLock
  1270. //========================================================================================
  1271.  
  1272. FW_DEFINE_AUTO(FW_CPrivMacPixelLock)
  1273.  
  1274. //----------------------------------------------------------------------------------------
  1275. // FW_CPrivMacPixelLock::FW_CPrivMacPixelLock
  1276. //----------------------------------------------------------------------------------------
  1277.  
  1278. FW_CPrivMacPixelLock::FW_CPrivMacPixelLock(FW_HBitmap rep) :
  1279.     fBitmap(rep)
  1280. {
  1281.     fPixMapHandle = FW_PrivBitmap_MacLockPixels(fBitmap);
  1282.  
  1283.     FW_END_CONSTRUCTOR
  1284. }
  1285.  
  1286. //----------------------------------------------------------------------------------------
  1287. // FW_CPrivMacPixelLock::~FW_CPrivMacPixelLock
  1288. //----------------------------------------------------------------------------------------
  1289.  
  1290. FW_CPrivMacPixelLock::~FW_CPrivMacPixelLock()
  1291. {
  1292.     FW_START_DESTRUCTOR
  1293.  
  1294.     FW_PrivBitmap_MacUnlockPixels(fBitmap);
  1295. }
  1296.  
  1297. //----------------------------------------------------------------------------------------
  1298. // FW_CPrivMacPixelLock::GetPixMapHandle
  1299. //----------------------------------------------------------------------------------------
  1300.  
  1301. PixMapHandle FW_CPrivMacPixelLock::GetPixMapHandle() const
  1302. {
  1303.     return fPixMapHandle;
  1304. }
  1305.  
  1306. #endif
  1307.